﻿package com.snzflash.components.slideshow 
{
	import com.snzflash.components.ComponentBase;
	import flash.events.Event;
	import flash.events.TimerEvent;
	import flash.utils.Timer;
	import gs.TweenLite;
	
	/**
	 * Базовый класс для слайдшоу
	 * по умолчанию переключение через альфу
	 * @author firsoff maxim, tel: +79222345364, skype: maxim.firsoff
	 */
	public class SlideshowBase extends ComponentBase
	{
		// авто старт при получении данных
		public var autoStart:Boolean = true;
		// зацикленное воспроизведение
		public var loop:Boolean = true;
		
		// политика переключения
		protected var _switchPolicy:String = SWITCH_POLICY_WAIT;
		// политика ресайза
		protected var _resizePolicy:String = RESIZE_POLICY_MINIMUM;
		
		// готовое, загруженное изображение
		protected var _image:SlideshowItemBase;
		// текущее загружаемое изображение
		protected var _loadingImage:SlideshowItemBase;
		
		protected var _images:/*SlideshowItemBase*/Array;
		// время переключения
		protected var _switchDelay:Number = 7000;
		// время эффекта
		protected var _effectDuration:Number = 0.5;
		// таймер переключатель
		protected var _switchTimer:Timer;
		// индекс
		protected var _index:int = 0; // указатель на загрузку
		// состояние
		protected var _state:String;
		
		// политика загрузки/смены изображений
		public static const SWITCH_POLICY_WAIT:String = 'SWITCH_POLICY_WAIT';				//	 ожидание текущей загрузки и потом смена
		public static const SWITCH_POLICY_IMMEDIATE:String = 'SWITCH_POLICY_IMMEDIATE';		//	 немедленная смена текущей фотки
		// политика ресайза
		public static const RESIZE_POLICY_MAXIMUM:String = 'RESIZE_POLICY_MAXIMUM';
		public static const RESIZE_POLICY_MINIMUM:String = 'RESIZE_POLICY_MINIMUM';
		
		public static const STATE_PLAYING:String = 'STATE_PLAYING';		
		public static const STATE_PAUSED:String = 'STATE_PAUSED';		
		
		
		/**
		 * Конструктор
		 */
		public function SlideshowBase() 
		{
			super();
		};
		
		/**
		 * Запуск с самого начала
		 */
		public function start():void 
		{
			// если данных нет, или их мало - выход
			if (!_data || (_data as Array).length < 2) return;
			_state = STATE_PLAYING;
			_index = 0
			switchImage(0);
		}
		
		/**
		 * Приостановка
		 */
		public function pause():void 
		{
			_state = STATE_PAUSED;
		};
		
		/**
		 * С текущего места
		 */
		public function resume():void 
		{
			if (_state == STATE_PAUSED) next();
			_state = STATE_PLAYING;
		};
		
		public function next():void 
		{
			var i:int = _index + 1;
			if (loop) 
			{
				i = i > dataArray.length - 1 ? 0 : i;
				switchImage(i);
			}
			else 
			{
				if (i <= dataArray.length - 1 ) switchImage(i);
			}
			_index = i;
		}
		
		public function back():void 
		{
			var i:int = _index - 1;
			if (loop) 
			{
				i = i < 0 ? dataArray.length - 1 : i;
				switchImage(i);
			}
			else 
			{
				if (i >= 0) switchImage(i);
			}
			_index = i;
		}
		
		override protected function create():void 
		{
			super.create();
			
			_images = new Array();
			
			// 1е изображение
			_image = new SlideshowItemBase();
			_image.alpha = 0;
			_image.addEventListener(Event.COMPLETE, onComplete);
			// 2 изображение
			_loadingImage = new SlideshowItemBase();
			_loadingImage.alpha = 0;
			_loadingImage.addEventListener(Event.COMPLETE, onComplete);
			// на всякий случай скидываем в массив
			_images.push(_image);
			_images.push(_loadingImage);
			
			addChild(_image);
			addChild(_loadingImage);
			// таймер
			_switchTimer = new Timer(_switchDelay);
			_switchTimer.addEventListener(TimerEvent.TIMER, onTimer);	
		};
		
		
		override protected function updateDisplayList():void 
		{
			super.updateDisplayList();
			
			// обновляем размеры автосайза
			_image.autoHeight = __height;
			_image.autoWidth = __width;
			_loadingImage.autoHeight = __height;
			_loadingImage.autoWidth = __width;
			
			// обновляем текущие размеры
			resize();
			// и позиции 
			_image.x = Math.round( (__width - _image.width) / 2);
			_image.y = Math.round( (__height- _image.height) / 2);
			_loadingImage.x = Math.round( (__width - _loadingImage.width) / 2);
			_loadingImage.y = Math.round( (__height- _loadingImage.height) / 2);
			
			
		};
		
		protected function resize():void
		{
			var scale:Number = 1;
			if (_image.loaded)
			{
				scale = _resizePolicy == RESIZE_POLICY_MAXIMUM ? Math.max(__width / _image.unscaledWidth, __height / _image.unscaledHeight) : Math.min(__width / _image.unscaledWidth, __height / _image.unscaledHeight);
				_image.scaleX = _image.scaleY = scale
			};
			
			if (_loadingImage.loaded)
			{
				scale = _resizePolicy == RESIZE_POLICY_MAXIMUM ? Math.max(__width / _loadingImage.unscaledWidth, __height / _loadingImage.unscaledHeight) : Math.min(__width / _loadingImage.unscaledWidth, __height / _loadingImage.unscaledHeight);
				_loadingImage.scaleX = scale				
			};
			
		};
		
		/**
		 * Переключить изображения
		 * @param	pointer
		 */
		protected function switchImage(pointer:int):void
		{
			//trace('switchImage : ' + pointer);
			_switchTimer.stop();
			//var target:SlideshowItemBase = _runned ? _loadingImage : _image;
			var target:SlideshowItemBase = _loadingImage;
			addChild(target)
			switch (_switchPolicy) 
			{
				case SWITCH_POLICY_WAIT:
					//trace(dataArray[pointer].url);
					target.data = dataArray[pointer];
					target.alpha = 0;
				break;
				
				case SWITCH_POLICY_IMMEDIATE:
					target.data = dataArray[pointer];
					target.alpha = 0;
				break;
			};
			
			
			//_runned = true;
			//if (_image.loaded)
			//{
				//
			//}
		};
		
		//protected function get freeImage():SlideshowItemBase 
		//{
			//var result:SlideshowItemBase;
			//
			//for each(var i:SlideshowItemBase  in _images) 
			//{
				//if(i.loaded
			//}
			//return ; 
			//
		//}
		
		protected function showImage(i:SlideshowItemBase):void
		{
			TweenLite.to (i, effectDuration, { alpha : 1, onComplete:onShowImage, onCompleteParams: [i] } );
		};
		
		protected function hideImage(i:SlideshowItemBase):void
		{
			TweenLite.to (i, effectDuration, { alpha : 0, onComplete:onHideImage, onCompleteParams: [i] } );
		};
		
		public function get switchPolicy():String { return _switchPolicy; };
		
		public function set switchPolicy(value:String):void 
		{
			// чтобы не было неправильного значения
			switch (value) 
			{
				case SWITCH_POLICY_WAIT:
					_switchPolicy = value;
				break;
				
				case SWITCH_POLICY_IMMEDIATE:
					_switchPolicy = value;
				break;
			}
		};
		
		/**
		 * для удобства
		 */
		protected function get dataArray():Array
		{
			return _data as Array;
		}
		override public function get data():Object { return super.data; };
		
		/**
		 * Данные - массив объектов {url:String, data:Object}
		 */
		override public function set data(value:Object):void 
		{
			super.data = value;
			if (autoStart) 
			{
				start();
			};
		};
		
		/**
		 * Время переключения
		 */
		public function get switchDelay():Number { return _switchDelay; };
		
		public function set switchDelay(value:Number):void 
		{
			_switchDelay = value;
			_switchTimer.delay = value;
		};
		
		/**
		 * Время действия эффекта
		 */
		public function get effectDuration():Number { return _effectDuration; };
		
		public function set effectDuration(value:Number):void 
		{
			_effectDuration = value;
		};
		
		/**
		 * Политика ресайза
		 */
		public function get resizePolicy():String { return _resizePolicy; };
		
		public function set resizePolicy(value:String):void 
		{
			_resizePolicy = value;
		};
		
		/**
		 * При срабатывании таймера просто показываем следующую
		 * @param	event
		 */
		protected function onTimer(event:TimerEvent):void 
		{
			next();
		};
		
		/**
		 * При загрузке изображения
		 * @param	event
		 */
		protected function onComplete(event:Event):void 
		{
			// если слайдшоу играет то запускаем таймер
			if (_state == STATE_PLAYING ) { _switchTimer.start() }
			// целевое изображение
			var target:SlideshowItemBase = SlideshowItemBase(event.target);
			switch (_switchPolicy) 
			{
				case SWITCH_POLICY_WAIT:
					
					
					_loadingImage = target == _loadingImage ? _image : _loadingImage;
					_image = target;
					
					
					showImage(target);
					
					
				break;
				
				case SWITCH_POLICY_IMMEDIATE:
				
					_loadingImage = target == _loadingImage ? _image : _loadingImage;
					_image = target;
					showImage( target );
					hideImage(_loadingImage);
				break;
			};
			
			invalidate();
			//_image = SlideshowItemBase(event.target);
			//_image.loaded = true;
		};
		
		protected function onHideImage(...rest):void
		{
			var target:SlideshowItemBase = rest[0];
			target.scaleX = target.scaleX = 1;
			target.x = target.y= 0;
		};
		
		protected function onShowImage(...rest):void
		{
			//_switchTimer.start();
			switch (_switchPolicy) 
			{
				case SWITCH_POLICY_WAIT:
					hideImage(_loadingImage);
				break;
				
				case SWITCH_POLICY_IMMEDIATE:
					
				break;
			}
		};
		
	}

}